#include "mythread.h"
#include "thread_pool.h"

Mythread::Mythread(int id):_tid(id)
{
    _t_handel=nullptr;
    _status=StatusCode::STOP;
}


Mythread::~Mythread()
{
    if(_status!=StatusCode::STOP)
        close();
    //delete _t_handel;
}

Mythread::Mythread(Mythread&& t)
{
    this->_status.store(t._status.load());
    this->_t_handel=t._t_handel;
    this->_tid=t._tid;
    t._t_handel=nullptr;
}
Mythread& Mythread::operator=(Mythread&& t)
{
    this->_status.store(t._status.load());
    this->_t_handel=t._t_handel;
    this->_tid=t._tid;
    t._t_handel=nullptr;
    return *this;
}

int Mythread::invoke(ThreadPool& pool)
{
    try
    {
        this->_status.store(StatusCode::BLOCK);
        this->_t_handel=new std::thread(&Mythread::MainThread,this,std::ref(pool)); //启动线程

        printf("[thread: %d]   启动成功\n",_tid);
        
        return 0;
    }
    catch(const std::exception& e)
    {
        printf("[thread: %d]   启动失败\n",_tid);

        this->_status.store(StatusCode::STOP);
        std::cerr << e.what() << '\n';
    }
    return -1;
}

int Mythread::close()
{
    if(this->_status.load()!=StatusCode::STOP)
    {
        try
        {     
            this->_status.store(StatusCode::STOP);

            //pthread_cancel(_t_handel->native_handle());     //向线程发送取消信号
            this->_t_handel->detach();        //回收资源,不会发生阻塞
            delete _t_handel;
            _t_handel=nullptr;
            printf("[thread: %d]   关闭成功\n",_tid);
        }
        catch(const std::exception& e)
        {
            printf("[thread: %d]   关闭失败\n",_tid);
            std::cerr << e.what() << '\n';
            return -1;
        }
    }
    return 0;
}

void Mythread::MainThread(ThreadPool& pool)
{
    TaskQueue::Task task;
    while(this->_status.load()!=StatusCode::STOP)
    {
        {
            std::unique_lock<std::mutex> _qmutex(pool._COND_M);
            _status.store(StatusCode::BLOCK);
            pool._COND.wait(_qmutex,[&pool]()
            {
                return !pool.empty();
            });
            task=std::move(pool.get_one_task());
        }
        _status.store(StatusCode::RUN);
        task();
    }
}

Mythread::ThreadStatus Mythread::CheckThrreadStatus()
{
    ThreadStatus temp;
    temp._code=_status.load();
    temp._tid=_tid;
    return temp;
}
